package delayqueue

import (
	"context"
	"encoding/json"
	"github.com/go-basic/uuid"
	"github.com/go-redis/redis"
	"time"
)

const (
	RetryNum      = 2 // 最大重试次数
	RetryInterval = 1 // 重试时间间隔(秒)
)

// Message ...
type Message struct {
	MsgId         string      `json:"msg_id"`
	Body          interface{} `json:"body"`
	RunTime       string      `json:"run_time"`       // 运行时间
	RetryNum      uint64      `json:"retry_num"`      // 最大重试次数
	RetryInterval int64       `json:"retry_interval"` // 重试时间间隔(秒)
}

// Push ...
func Push(ctx context.Context, topic string, body interface{}, delayTime time.Duration) (string, error) {
	m := &manager{
		topic: topic,
	}

	runTime := time.Now().Add(delayTime)
	msgId := uuid.New()
	data := &Message{
		MsgId:         msgId,
		Body:          body,
		RunTime:       runTime.Format("2006-01-02 15:04:05"),
		RetryInterval: RetryInterval,
	}
	member, err := json.Marshal(data)
	if err != nil {
		return "", err
	}

	// save hash
	err = m.saveTask(msgId, member)
	if err != nil {
		return "", err
	}

	score := float64(runTime.UnixNano())
	z := []redis.Z{
		{
			Score:  score,
			Member: msgId,
		},
	}

	// save zset
	err = m.addTask(z)
	if err != nil {
		return "", err
	}

	return msgId, nil
}

// Delete ...
func Delete(ctx context.Context, msgId string) error {
	m := &manager{}

	// del hash
	err := m.delTask(msgId)
	if err != nil {
		return err
	}

	// del zset
	err = m.remTask(msgId)
	if err != nil {
		return err
	}

	return nil
}
